

#ifndef _SOMB_H_
#define _SOMB_H_

#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>

#define SOMB_VERSION	("V0.2.3")

#define SOMB_NS_MAX         (16)

#define SOMB_OK          0
#define SOMB_FAIL        -1
#define SOMB_TIMEOUT     -2
#define SOMB_PARAM_ERR   -3
#define SOMB_INVALID_FD  -4
#define SOMB_SERVICEID_INVALID   -5
#define SOMB_MSG_ENCODE_ERR      -6
#define SOMB_MSG_DECODE_ERR      -7
#define SOMB_MSG_ID_ERR          -8
#define SOMB_LENGTH_ERR          -9
#define SOMB_REG_FAILED          -10


typedef enum
{
    SOMB_SVC_TYPE_INVALID,
    SOMB_SVC_TYPE_METHOD,
    SOMB_SVC_TYPE_EVENT,
    SOMB_SVC_TYPE_MAX,
}E_SOMB_SVC_TYPE;

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
/***************************************************************
 *              SOMB Init APIs 
 * *************************************************************/
extern int32_t i32SOMB_SubNs_Init(uint32_t *pSubNsId);


/***************************************************************
 *              SOMB Deppoy/Destory Service APIs 
 * *************************************************************/
extern void ** vSOMB_Service_Instance_New();
extern int32_t i32SOMB_Service_Add(void **Instance,uint32_t ServiceId,E_SOMB_SVC_TYPE ServiceType,void *pfFunc);
extern int32_t i32SOMB_Service_Instance_Deploy(void **Instance);
extern int32_t i32SOMB_Service_Instance_Destroy(void **Instance);
extern int32_t i32SOMB_Service_SetAvailable(uint32_t ServiceIdList[], uint32_t ListLength, bool bAvailable);
extern int32_t i32SOMB_Service_SetAvailableWithMask(uint32_t mask,uint32_t mask_value, bool bAvailable);


/***************************************************************
 *              SOMB Method APIS
 * *************************************************************/
typedef void (*PF_SOMB_METHOD_PROVIDER)(uint32_t handle,uint32_t ServiceId,void*MthReqData,uint32_t MthReqDataLen);
typedef void (*PF_SOMB_METHOD_ASYNC_CB)(uint32_t ServiceId,void*MthRespData,uint32_t MthRespDataLen);
/*The Service Productor could provide method service on SOMB by following APIs*/
extern int32_t i32SOMB_Method_Complete(uint32_t handle,uint32_t ServiceId,void* MthRespData,uint32_t MthRespDataLen);
/*The Service Consumer could request Method service on SOMB by following APIs*/
extern int32_t i32SOMB_Method_Request_Sync(uint32_t ServiceId, void *MthReqData, uint32_t MthReqDataLen,void *MthRespData, uint32_t *MthRespDataLen,uint32_t timeout_ms);
extern int32_t i32SOMB_Method_Request_Async(uint32_t ServiceId, void *MthReqData, uint32_t MthReqDataLen,PF_SOMB_METHOD_ASYNC_CB pfMthAsyncFunc);
extern int32_t i32SOMB_Method_SetRequest(uint32_t ServiceId,void *InData,uint32_t InDataLen);



/***************************************************************
 *              SOMB Event APIS
 * *************************************************************/
typedef int32_t (*PF_SOMB_EVENT_ON_LISTEN_CB)(uint32_t ServiceId,void**EvtData,uint32_t *EvtDataLen);
typedef void (*PF_SOMB_EVENT_LISTENER_CB)(uint32_t ServiceId,void*EvtData,uint32_t EvtDataLen);
typedef void (*PF_SOMB_METHOD_ON_AVAILABLE_CB)(uint32_t ServiceId,bool bAvailable);
/*The Service Productor could provide trigger event service on SOMB by following APIs*/
extern int32_t i32SOMB_Event_Trigger(uint32_t ServiceId,void *EventData,uint32_t EventDataLen);
/*The Service Consumer could listen event service on SOMB by following APIs*/

typedef enum{
   /*flags for event service*/ 
    SOMB_SVC_FLAGS_EVENT_LISTEN_SYNC_DATA = 0x01,

   /*flags for method service*/ 
}SOMB_SERVIRCE_FLAGS;
typedef struct
{
    SOMB_SERVIRCE_FLAGS flags;
    PF_SOMB_EVENT_LISTENER_CB pfListenerCB;
}ST_SOMB_SERVICE_EVENT_LISTENER_CONFIG;

typedef struct
{
    uint32_t ServiceId;
    uint32_t ServiceType;
    union
    {
#define OnAvailableCB u.pfOnAvailableCB
        PF_SOMB_METHOD_ON_AVAILABLE_CB pfOnAvailableCB;
#define ListenerFlags u.evl.flags
#define ListenerCB u.evl.pfListenerCB
        ST_SOMB_SERVICE_EVENT_LISTENER_CONFIG evl; 
    }u;
}ST_SOMB_SERVICE_LISTEN_INFO;

extern int32_t i32SOMB_ServiceListener_Add(ST_SOMB_SERVICE_LISTEN_INFO ListenList[],uint32_t ListLength);
extern int32_t i32SOMB_EventListener_Delete(uint32_t ServiceIdList[],uint32_t ListLength);

typedef enum
{
    SOMB_SERVICE_CTRL_CMD_SET_STATUS , //refer to ST_SOMB_SERVICE_STATUS
    SOMB_SERVICE_CTRL_CMD_GET_STATUS ,//refer to ST_SOMB_SERVICE_STATUS
    SOMB_SERVICE_CTRL_CMD_SET_AUTHORITY_BLACKLIST ,//refer to ST_SOMB_SERVICE_AUTHORITY_STATUS
    SOMB_SERVICE_CTRL_CMD_GET_AUTHORITY_BLACKLIST ,//refer to ST_SOMB_SERVICE_AUTHORITY_STATUS
}E_SOMB_SERVICE_CTRLCMD;

typedef struct
{
    bool status;
}ST_SOMB_SERVICE_STATUS;

typedef struct
{
    uint32_t BlackList_Count;
    uint32_t BlackList_NsId[SOMB_NS_MAX];
}ST_SOMB_SERVICE_BLACKLIST;

extern int32_t i32SOMB_ServiceCtrl(uint32_t ServiceId,E_SOMB_SERVICE_CTRLCMD CtrlCmd,void *CmdData);


#include "pb.h"
#include "pb_encode.h"
#include "pb_decode.h"

extern bool sob_message_bytes_encode(pb_ostream_t *stream, const pb_field_t *field, void * const *arg);
#define SOMB_INIT_BYTES_ENCODE_BUFFER(bytes,buffer,buffer_len)\
            {\
                bytes.arg = &buffer;\
                bytes.funcs.encode = sob_message_bytes_encode; \
            };

extern bool sob_message_bytes_decode(pb_istream_t *stream, const pb_field_t *field, void **arg);
#define SOMB_INIT_BYTES_DECODE_BUFFER(bytes,buffer,buffer_len)\
            {\
                memset(buffer,0,buffer_len);\
                bytes.arg = &buffer;\
                bytes.funcs.decode = sob_message_bytes_decode; \
            };


extern int32_t i32SOMB_Message_Encode(uint8_t *pBuffer,uint32_t *pBufferSize,void *pMsg,const pb_msgdesc_t *fields);
#define SOMB_MESSAGE_ENCODE(MsgName,pMsg,pBuffer,pBufferSize) \
    i32SOMB_Message_Encode(pBuffer,pBufferSize,(void*)pMsg,MsgName##_fields);

extern int32_t i32SOMB_Message_Decode(uint8_t *pBuffer,uint32_t BufferSize,void *pMsg,uint32_t MsgSize,const pb_msgdesc_t *fields);
#define SOMB_MESSAGE_DECODE(MsgName,pMsg,pBuffer,BufferSize) \
    i32SOMB_Message_Decode(pBuffer,BufferSize,pMsg,sizeof(MsgName),MsgName##_fields);


#define SOMB_ALLOC(size) malloc(size);
#define SOMB_FREE(pBuffer) free(pBuffer);

#endif // _SOMB_H_
